﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using RAP.Framework.Libary.DataSource.Model;
using RAP.Framework.Libary.Utils;

namespace RAP.Framework.Libary.DataSource.DataReader
{
  /// <summary>
  /// JSON字符串解析器
  /// </summary>
  public class JSONStringParser : DataReaderParser
  {
    /// <summary>
    /// 
    /// </summary>
    public JSONStringParser()
    {
      var settingHandler = JsonConvert.DefaultSettings;
      JsonSerializerSettings settings = null;
      if (settingHandler == null)
      {
        settings = new JsonSerializerSettings();
        JsonConvert.DefaultSettings = settingHandler = new Func<JsonSerializerSettings>(() =>
       {
         return settings;
       });
      }
      settings = settingHandler();
      if (settings.Converters.FirstOrDefault(p => p.GetType() == typeof(JSONStringSerializer)) == null)
      {
        settings.Converters.Add(new JSONStringSerializer());
      }
    }

    /// <summary>
    /// 将DataReader当前结果集转换成JSON字符串
    /// </summary>
    /// <param name="dataReader"></param>
    /// <param name="pickFields">读取第一条记录的指定列，默认读取所有数据的所有列</param>
    /// <param name="type">结果类型名称</param>
    /// <param name="parseContext">解析时用到的上下文对象</param>
    /// <returns></returns>
    public override ParseResult ParseData(IDataReader dataReader, IList pickFields, string type, DataParseContext parseContext)
    {
      var jsonBuilder = CreateDataModel() as StringBuilder;
      var fieldCount = dataReader.FieldCount;
      var fields = this.GetFields(dataReader, pickFields);
      var onlyGetFirstData = pickFields.IsNotNullOrEmpty();
      var dataCount = 0;
      jsonBuilder.Append("[");
      while (dataReader.Read())
      {
        if (dataCount > 0)
        {
          jsonBuilder.Append(",");
        }
        jsonBuilder.Append("{");
        for (var col = 0; col < fields.Count; col++)
        {
          var field = fields[col];
          var val = GetDBValue(dataReader, field);
          var quotes = string.Empty;
          var isString = val.IsString();
          var isDateTime = isString ? false : val.IsDateTime();
          if (val != null)
          {
            if((isString || isDateTime))
            {
              quotes = "\"";
            }
          }
          else
          {
            val = "null";
          }
          if (val != null && isDateTime)
          {
            val = ((DateTime)val).ToString("yyyy-MM-dd HH:mm:ss");
          }
          else if (val is bool)
          {
            val = val.ToString().ToLower();
          }
          if (col > 0)
          {
            jsonBuilder.Append(",");
          }
          jsonBuilder.Append($"\"{field.Name}\":{quotes}{val}{quotes}");
        }
        jsonBuilder.Append("}");

        dataCount++;
        if (onlyGetFirstData)
        {
          break;
        }
      }
      jsonBuilder.Append("]");
      return new ParseResult
      {
        DataValue = new StringValueJSONSerializer(jsonBuilder.ToString()),
        DataCount = dataCount
      };
    }

    /// <summary>
    /// 创建数据模型对象
    /// </summary>
    /// <param name="resultTypeName">结果模型类型名称</param>
    /// <param name="properites">属性值集合</param>
    /// <returns></returns>
    public override object CreateDataModel(string resultTypeName = null, IDictionary properites = null)
    {
      var jsonBuilder = new StringBuilder(256);
      if (properites.IsNotNullOrEmpty())
      {
        jsonBuilder.Append('{');
        var col = 0;
        foreach (DictionaryEntry ety in properites)
        {
          var val = ety.Value;
          var quotes = string.Empty;
          var isDateTime = val.IsDateTime();
          if (val.IsString() || isDateTime)
          {
            quotes = "\"";
          }
          if (isDateTime)
          {
            val = ((DateTime)val).ToString("yyyy-MM-dd HH:mm:ss");
          }
          if (col > 0)
          {
            jsonBuilder.Append(",");
          }
          jsonBuilder.Append($"\"{ety.Key}\":{quotes}{val}{quotes}");
          col++;
        }
        jsonBuilder.Append('}');
      }
      return jsonBuilder;
    }
  }

  /// <summary>
  /// 自定义字符串值JSON序列化器
  /// </summary>
  public class StringValueJSONSerializer
  {
    /// <summary>
    /// 
    /// </summary>
    public string JSONValue { get; set; }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="val"></param>
    public StringValueJSONSerializer(string val = null)
    {
      JSONValue = val;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
      return JSONValue;
    }
  }

  /// <summary>
  /// 
  /// </summary>
  public class JSONStringSerializer : CustomCreationConverter<StringValueJSONSerializer>
  {
    /// <summary>
    /// 
    /// </summary>
    /// <param name="objectType"></param>
    /// <returns></returns>
    public override StringValueJSONSerializer Create(Type objectType)
    {
      return new StringValueJSONSerializer();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="value"></param>
    /// <param name="serializer"></param>
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      if (value == null)
      {
        writer.WriteNull();
      }
      else
      {
        writer.WriteRawValue(value.ToString());
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool CanWrite => true;
  }

}
